package com.demo.key.pa

import android.Manifest
import android.animation.ValueAnimator
import android.content.Intent
import android.net.Uri
import android.net.VpnService
import android.view.Gravity
import android.view.View
import android.view.animation.LinearInterpolator
import androidx.appcompat.app.AlertDialog
import androidx.recyclerview.widget.LinearLayoutManager
import com.demo.key.R
import com.demo.key.adap.Server0822Adapter
import com.demo.key.listeners.IConnectTimeListener
import com.demo.key.listeners.IStateChangedListener
import com.demo.key.load_admob.AdmobKeyType
import com.demo.key.load_admob.LoadAdmob0822Manager
import com.demo.key.server.ConnectServer0822Manager
import com.demo.key.server.ConnectTime0822Manager
import com.demo.key.server.Server0822Entity
import com.demo.key.show_admob.ShowFullAd0822
import com.demo.key.show_admob.ShowNativeAd0822
import com.demo.key.util.*
import com.github.shadowsocks.bg.BaseService
import com.github.shadowsocks.utils.StartService
import kotlinx.android.synthetic.main.activity_home.*
import kotlinx.android.synthetic.main.home_bottom.*
import kotlinx.android.synthetic.main.layout_home.*
import kotlinx.android.synthetic.main.layout_server.*

class Home0822Pa:Abs0822Page(), IConnectTimeListener, IStateChangedListener {
    private var isConnect=true
    private var canClickConnectBtn=true
    private var hasPermission = false
    private var connectAnimator: ValueAnimator?=null

    private val showConnectAd by lazy { ShowFullAd0822(this, AdmobKeyType.CONNECT){ showResultPage() } }
    private val showBackAd by lazy { ShowFullAd0822(this, AdmobKeyType.BACK){  } }
    private val showHomeNativeAd by lazy { ShowNativeAd0822(this,AdmobKeyType.HOME) }

    override fun layoutId(): Int = R.layout.activity_home

    override fun view() {
        showHome(true)
        ConnectServer0822Manager.initShadowsocksConnection(this)
        ConnectTime0822Manager.addTimeListener(this)
        ConnectServer0822Manager.setIStateChangedListener(this)
        updateCurrentServerInfo()
        setClick()
    }

    private fun setAdapter(){
        recycler_view.apply {
            layoutManager=LinearLayoutManager(this@Home0822Pa)
            adapter=Server0822Adapter(this@Home0822Pa){
                clickServerItem(it)
            }
        }
    }

    private fun clickServerItem(server0822Entity: Server0822Entity){
        var click=""
        val current = ConnectServer0822Manager.current
        val connected = ConnectServer0822Manager.connected()
        if (current.host_key0822==server0822Entity.host_key0822){
            if (!connected){
                click="connect"
            }
        }else{
            click=if (connected) "disconnect" else "connect"
        }
        if (click=="disconnect"){
            showDialog {
                clickServerResult(click,server0822Entity)
            }
        }else{
            clickServerResult(click,server0822Entity)
        }
    }

    private fun clickServerResult(action:String,server0822Entity: Server0822Entity){
        showHome(true)
        ConnectServer0822Manager.current=server0822Entity
        if (action=="connect"){
            updateCurrentServerInfo()
            clickConnectBtn(true)
        }else if (action=="disconnect"){
            clickConnectBtn(false)
        }
    }

    private fun showDialog(sure:()->Unit){
        AlertDialog.Builder(this).apply {
            setMessage("You are currently connected and need to disconnect before manually connecting to the server.")
            setPositiveButton("sure", { dialog, which ->
                sure.invoke()
            })
            setNegativeButton("cancel",null)
            show()
        }
    }


    private fun setClick(){
        ll_home.setOnClickListener {
            if (canClickConnectBtn){
                showHome(true)
                showBackAd()
            }
        }
        ll_server.setOnClickListener {
            if (canClickConnectBtn){
                showHome(false)
                LoadAdmob0822Manager.logic(AdmobKeyType.BACK)
                setAdapter()
            }
        }
        iv_connect_center_icon.setOnClickListener {
            if (canClickConnectBtn){
                clickConnectBtn(!ConnectServer0822Manager.connected())
            }
        }
        iv_open_drawer.setOnClickListener {
            if (!drawer_layout.isOpen&&canClickConnectBtn){
                drawer_layout.openDrawer(Gravity.LEFT)
            }
        }

        llc_contact.setOnClickListener {
            try {
                val intent = Intent(Intent.ACTION_SENDTO)
                intent.data= Uri.parse("mailto:")
                intent.putExtra(Intent.EXTRA_EMAIL,Conf0822.EMAIL)
                startActivity(intent)
            }catch (e:Exception){
                toast("Contact us by email：${Conf0822.EMAIL}")
            }
        }
        llc_agree.setOnClickListener {
            startActivity(Intent(this,Agree0822Pa::class.java))
        }
        llc_share.setOnClickListener {
            shareApp()
        }
        llc_update.setOnClickListener {
            updateApp()
        }
    }

    private fun clickConnectBtn(connect:Boolean){
        canClickConnectBtn=false
        LoadAdmob0822Manager.logic(AdmobKeyType.CONNECT)
        LoadAdmob0822Manager.logic(AdmobKeyType.RESULT)

        if (connect){
            if (getNetWorkStatus(this) ==1){
                AlertDialog.Builder(this).apply {
                    setMessage("You are not currently connected to the network")
                    setPositiveButton("sure", null)
                    show()
                }
                canClickConnectBtn=true
                return
            }
            if (VpnService.prepare(this) != null) {
                hasPermission = true
                launcher.launch(null)
                return
            }
            connectServer()
        }else{
            ConnectServer0822Manager.disconnect()
            updateConnectUI(BaseService.State.Stopping)
            startConnectAnimator(false)
        }
    }

    private fun connectServer(){
        ConnectServer0822Manager.connect()
        ConnectTime0822Manager.resetConnectTime()
        updateConnectUI(BaseService.State.Connecting)
        startConnectAnimator(true)
    }

    private fun startConnectAnimator(connect:Boolean){
        isConnect=connect
        connectAnimator = ValueAnimator.ofInt(0, 100).apply {
            duration=10000L
            interpolator = LinearInterpolator()
            addUpdateListener {
                val p = it.animatedValue as Int
                val duration = (10 * (p / 100.0F)).toInt()
                if (duration in 2..9){
                    if (ConnectServer0822Manager.actionComplete(connect)&&showConnectAd.loadFullAdFinish()){
                        stopConnectAnimator()
                        connectResult(toResult = false)
                        showConnectAd.show()
                    }
                }else if (duration>=10){
                    connectResult()
                }
            }
            start()
        }
    }

    private fun connectResult(toResult:Boolean=true){
        if (ConnectServer0822Manager.actionComplete(isConnect)){
            if (isConnect){
                updateConnectUI(BaseService.State.Connected)
            }else{
                updateConnectUI(BaseService.State.Stopped)
                updateCurrentServerInfo()
            }
            if (toResult){
                showResultPage()
            }
            canClickConnectBtn=true
        }else{
            toast(if (toResult) "Connect Fail" else "Disconnect Fail")
            updateConnectUI(BaseService.State.Stopped)
            canClickConnectBtn=true
        }
    }

    private fun showResultPage(){
        if (Activity0822Callback.front0822){
            val intent = Intent(this, Result0822Pa::class.java)
            intent.putExtra("connect",isConnect)
            startActivity(intent)
        }
    }

    private fun stopConnectAnimator(){
        connectAnimator?.removeAllUpdateListeners()
        connectAnimator?.cancel()
        connectAnimator=null
    }

    private val launcher = registerForActivityResult(StartService()) {
        if (!it && hasPermission) {
            hasPermission = false
            connectServer()
        } else {
            canClickConnectBtn=true
            toast("Connected fail")
        }
    }

    private fun showHome(show:Boolean){
        layout_home.show(show)
        layout_server.show(!show)
        iv_home_icon.isSelected=show
        tv_home_text.isSelected=show
        iv_server_icon.isSelected=!show
        tv_server_text.isSelected=!show
    }

    override fun connectTimeListener(time: String) {
        tv_connect_time.text=time
    }

    private fun updateConnectUI(state: BaseService.State){
        when(state){
            BaseService.State.Connected->{
                connecting_lottie_view.show(false)
                tv_center_connect_state.text="Connected"
                iv_connect_center_icon.setImageResource(R.drawable.icon_home_center_connected)
            }
            BaseService.State.Stopped,BaseService.State.Idle->{
                connecting_lottie_view.show(false)
                tv_center_connect_state.text="Connect"
                tv_connect_time.text="00:00:00"
                iv_connect_center_icon.setImageResource(R.drawable.icon_home_center_idle)
            }
            BaseService.State.Connecting->{
                connecting_lottie_view.show(true)
                tv_center_connect_state.text="Connecting"
                iv_connect_center_icon.setImageResource(R.drawable.icon_home_center_idle)
            }
            BaseService.State.Stopping->{
                connecting_lottie_view.show(true)
                tv_center_connect_state.text="Stopping"
                iv_connect_center_icon.setImageResource(R.drawable.icon_home_center_idle)
            }
            else->{}
        }
    }

    override fun stateChanged(state: BaseService.State) {
        when(state){
            BaseService.State.Connected->{
                connecting_lottie_view.show(false)
                tv_center_connect_state.text="Connected"
            }
            BaseService.State.Stopped->{
                if (canClickConnectBtn){
                    connecting_lottie_view.show(false)
                    tv_center_connect_state.text="Connect"
                    tv_connect_time.text="00:00:00"
                }
            }
            else->{}
        }
    }

    private fun updateCurrentServerInfo(){
        iv_center_flag_icon.setImageResource(serverFlagRes(ConnectServer0822Manager.current.country_key0822))
    }

    private fun showBackAd(){
        if (showBackAd.loadFullAdFinish()){
            showBackAd.show()
        }
    }

    override fun onResume() {
        super.onResume()
        if (Activity0822Callback.refreshHomeNativeAd&&layout_home.visibility==View.VISIBLE){
            showHomeNativeAd.loopCheckHasNativeAd()
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        ConnectServer0822Manager.onDestroy()
        stopConnectAnimator()
        Activity0822Callback.refreshHomeNativeAd=true
        showHomeNativeAd.onDestroy()
        ConnectTime0822Manager.deleteTimeListener(this)
    }

}